{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c95d9175-9360-4563-9df5-ce46d7f41a1a",
   "metadata": {},
   "source": [
    "# Axis Options\n",
    "\n",
    "Customization options for axis appearance and behavior, including labels, limits, tick formatting, and axis scaling:\n",
    "\n",
    "```{eval-rst}\n",
    ".. plotting-options-table:: Axis Options\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bdb97e9e-cb1f-4fe3-bc6b-0e450fb3ffa8",
   "metadata": {},
   "source": [
    "(option-autorange)=\n",
    "## `autorange`\n",
    "\n",
    "The `autorange` option allows enabling autoranging on the x or y axis. When enabled, the range of the selected axis is automatically computed and updated based on the data range in that axis. Setting `autorange=\"y\"` is practical for inspecting closely long timeseries, as it zooming and panning actions will always end up focusing on the timeseries, which can be cumbersome without autoranging.\n",
    "\n",
    "In the example below, zoom and pan the second plot to observe the effect of y-axis autoranging. Note that this feature *does not* require an interactive Python kernel."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0816cd61-f0fb-4c58-a6ff-6117406345b8",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.stocks(\"pandas\").set_index(\"date\")[\"Apple\"]\n",
    "\n",
    "df.hvplot.line(autorange=None, width=300, title=\"No y-axis autoranging\") +\\\n",
    "df.hvplot.line(autorange=\"y\", width=300, shared_axes=False, title=\"y-axis autoranging\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0b2de446-161d-49c0-a252-b65dc3130e32",
   "metadata": {},
   "source": [
    "(option-flip_xaxis)=\n",
    "(option-flip_yaxis)=\n",
    "(option-flip_xaxis_flip_yaxis)=\n",
    "## `flip_xaxis / flip_yaxis`\n",
    "\n",
    "These options allow to flip the x and y axis. The examples below show their effect, notice how the axes, when flipped, start with a value of about 2 which then decreases."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "54250986-38eb-469e-a3a7-2d11eaaf22c1",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\n",
    "    \"x\": list(range(3)), \"y\": list(range(3)),\n",
    "    \"v\": [\"a\", \"b\", \"c\"], \"s\": list(range(100, 700, 200)),\n",
    "})\n",
    "\n",
    "plot_opts = dict(\n",
    "    x=\"x\", y=\"y\", color=\"v\", s=\"s\", legend=False,\n",
    "    aspect=1, frame_width=200, shared_axes=False,\n",
    ")\n",
    "(\n",
    "    df.hvplot.scatter(flip_xaxis=False, flip_yaxis=False, title=\"None\", **plot_opts) +\n",
    "    df.hvplot.scatter(flip_xaxis=True, flip_yaxis=False, title=\"flip_xaxis\", **plot_opts) +\n",
    "    df.hvplot.scatter(flip_xaxis=False, flip_yaxis=True, title=\"flip_yaxis\", **plot_opts) +\n",
    "    df.hvplot.scatter(flip_xaxis=True, flip_yaxis=True, title=\"flip_xaxis + flip_yaxis\", **plot_opts)\n",
    ").cols(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a2a608b-6644-44ee-8f35-9b495d0e5406",
   "metadata": {},
   "source": [
    "(option-framewise)=\n",
    "## `framewise`\n",
    "\n",
    "hvPlot can generate plots that are composed of multiple frames in an animation or controlled with widgets, for instance with the [`groupby`](option-groupby) option. The `framewise` option allows to control whether the axis ranges are computed frame-by-frame or instead normalized across all the frames. `framewise` is `True` by default, meaning the axis ranges are not normalized but computed frame-by-frame. Setting `framewise` to `False` is useful to directly compare the frames.\n",
    "\n",
    "In the examples below update the widget value and observe the axis and colorbar ranges, you should see that they adapt to the data range with `framewise=True` (default) and stay constant with `framewise=False`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9ae7d7c1-8ffc-4824-9a01-b7c08bd46c37",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "plot_opts = dict(x=\"bill_length_mm\", y=\"bill_depth_mm\", groupby=\"island\", frame_width=300, dynamic=False)\n",
    "plot_default = df.hvplot.scatter(framewise=True, title=\"framewise=True (default)\", **plot_opts)\n",
    "plot_not_framewise = df.hvplot.scatter(framewise=False, title=\"framewise=False\", **plot_opts)\n",
    "plot_default"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "15ef0d67-17ed-463f-bc9e-0ab29a972a75",
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_not_framewise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "80054cfe-318f-45aa-82c2-5fd70fc52855",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.xarray  # noqa\n",
    "\n",
    "ds = hvplot.sampledata.air_temperature(\"xarray\").isel(time=slice(0, 2))\n",
    "\n",
    "plot_opts = dict(dynamic=False, frame_width=300)\n",
    "plot_not_framewise = ds.hvplot.image(framewise=False, title=\"framewise=False\", **plot_opts)\n",
    "plot_default = ds.hvplot.image(title=\"framewise=True\", **plot_opts)\n",
    "plot_default"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3b86fbc0-c14e-4ef7-8a38-253c9ce77d1c",
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_not_framewise"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "97fd5c16-4b21-4965-98c1-13765df7e380",
   "metadata": {},
   "source": [
    ":::{seealso}\n",
    "- [`groupby`](option-groupby)\n",
    "- [`shared_axes`](option-shared_axes) to control axis normalization and linking in a layout.\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8ce5582-0366-476f-9ff1-b8681db38c27",
   "metadata": {},
   "source": [
    "(option-invert)=\n",
    "## `invert`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "06f8ed48-f01b-4659-aa83-1ec481f09acc",
   "metadata": {},
   "source": [
    "The `invert` option swaps the x- and y-axis."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "60554427-1ea4-4c3c-95e9-86a8f1569094",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"cat\": [\"A\", \"B\", \"C\"], \"value\": [20, 10, 30]})\n",
    "\n",
    "plot_opts = dict(x=\"cat\", y=\"value\", aspect=1, frame_width=200)\n",
    "df.hvplot.bar(invert=False, title=\"invert=False (default)\", **plot_opts) +\\\n",
    "df.hvplot.bar(invert=True, title=\"invert=True\", **plot_opts)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a6a6f7ca-3455-4087-a2b7-c210712f3f3d",
   "metadata": {},
   "source": [
    "(option-logx)=\n",
    "(option-logy)=\n",
    "(option-logx_logy)=\n",
    "## `logx / logy`\n",
    "\n",
    "These options control whether the x and y axes are defined with a logarithmic scale."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2dfb6ca8-405c-4191-b0a1-fe9342a2447b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"x\":(x:= np.logspace(0.1, 3, 20)), \"y\": x ** 2})\n",
    "\n",
    "plot_opts = dict(x=\"x\", y=\"y\", aspect=1, frame_width=200, shared_axes=False)\n",
    "df.hvplot.scatter(logx=True, title=\"logx=True\", **plot_opts) +\\\n",
    "df.hvplot.scatter(logy=True, title=\"logy=True\", **plot_opts)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9c844d1-b1af-43ca-8856-ab722bc04132",
   "metadata": {},
   "source": [
    "(option-loglog)=\n",
    "## `loglog`\n",
    "\n",
    "This controls whether both the x and y axes are defined with a logarithmic scale."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7506f678-e00b-4f7c-8e71-6b559e30cdc8",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"x\":(x:= np.logspace(0.1, 3, 20)), \"y\": x ** 2})\n",
    "\n",
    "plot_opts = dict(x=\"x\", y=\"y\", aspect=1, frame_width=200, shared_axes=False)\n",
    "df.hvplot.scatter(loglog=True, title=\"loglog=True\", **plot_opts)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c99c129-4a1f-498b-9f67-889d51652b5e",
   "metadata": {},
   "source": [
    "(option-rot)=\n",
    "## `rot`\n",
    "\n",
    "The `rot` option rotates the x-axis ticks by the specified number of degrees (positive values only). It is useful to avoid the overlapping of long labels, as shown in the example below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8fa69646-fc41-48a3-aa56-b7c9fa3df36c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"name\": [\"Very Long Name 1\", \"Very Long Name 2\"], \"value\": [10, 20]})\n",
    "\n",
    "df.hvplot.bar(x=\"name\", y=\"value\", rot=45, width=150, height=300)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2ee0eacb-2e3a-430a-bbfc-0410ddf8d0f5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"name\": [\"Very Long Name 1\", \"Very Long Name 2\"], \"value\": [10, 20]})\n",
    "\n",
    "df.hvplot.bar(x=\"name\", y=\"value\", rot=45, invert=True, height=150, width=400)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3bc22b79-66d6-41de-b113-70e63f3b287e",
   "metadata": {},
   "source": [
    "(option-shared_axes)=\n",
    "## `shared_axes`\n",
    "\n",
    "hvPlot automatically normalizes, and links (for the Bokeh plotting backend), the axes of plots in a layout that share the same *variable/dimension name*. This behavior can be disabled by setting `shared_axes` to `False`.\n",
    "\n",
    "The first three examples below demonstrate the *default* (`shared_axes=True`) behavior of hvPlot. In this first example, the layout contains two plots that share different data values but the same variable names `'x'` and `'y'`. Panning and zooming the plot, you can see the axes are linked."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c8e3abb8-5e6e-4655-b505-4f4571a46891",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "df1 = pd.DataFrame({\"x\": (x:= np.linspace(-2*np.pi, 2*np.pi, 50)), \"y\": np.sin(x)})\n",
    "df2 = pd.DataFrame({\"x\": (x:= np.linspace(-5*np.pi, 5*np.pi, 50)), \"y\": 5*np.sin(x)})\n",
    "\n",
    "(\n",
    "    df1.hvplot.line(x=\"x\", y=\"y\", frame_width=200, aspect=1) +\n",
    "    df2.hvplot.line(x=\"x\", y=\"y\", frame_width=200, aspect=1)\n",
    ").opts(title=\"x and y axes shared\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "665024f1-b60e-433a-bc2d-7609be388183",
   "metadata": {},
   "source": [
    "In this example, only the y axis is linked as both plots just share the `'y'` dimension."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "41bc9a07-be14-42e2-9403-ab0b332bd5f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "df1 = pd.DataFrame({\"x1\": (x:= np.linspace(-2*np.pi, 2*np.pi, 50)), \"y\": np.sin(x)})\n",
    "df2 = pd.DataFrame({\"x2\": (x:= np.linspace(-5*np.pi, 5*np.pi, 50)), \"y\": 5*np.sin(x)})\n",
    "\n",
    "(\n",
    "    df1.hvplot.line(x=\"x1\", y=\"y\", frame_width=200, aspect=1) +\n",
    "    df2.hvplot.line(x=\"x2\", y=\"y\", frame_width=200, aspect=1)\n",
    ").opts(title=\"y axes shared\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "709e10f5-daed-45ad-9e3c-a66be9269689",
   "metadata": {},
   "source": [
    "In this example, only the x axis is linked as both plots just share the `'x'` dimension."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ce8b84ad-4b77-40e1-a4a5-dbcb4771ee45",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "df1 = pd.DataFrame({\"x\": (x:= np.linspace(-2*np.pi, 2*np.pi, 50)), \"y1\": np.sin(x)})\n",
    "df2 = pd.DataFrame({\"x\": (x:= np.linspace(-2*np.pi, 2*np.pi, 50)), \"y2\": 5*np.sin(x)})\n",
    "\n",
    "(\n",
    "    df1.hvplot.line(x=\"x\", y=\"y1\", frame_width=200, aspect=1) +\n",
    "    df2.hvplot.line(x=\"x\", y=\"y2\", frame_width=200, aspect=1)\n",
    ").opts(title=\"x axes shared\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c8746cdd-9680-4820-b019-a99dd83958a0",
   "metadata": {},
   "source": [
    "In order to disable shared axes, we need to set `shared_axed=False` to at *least the last* plot in the layout."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8a19f306-4de3-427b-b4b4-6ba1c419826e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "df1 = pd.DataFrame({\"x1\": (x:= np.linspace(-2*np.pi, 2*np.pi, 50)), \"y\": np.sin(x)})\n",
    "df2 = pd.DataFrame({\"x2\": (x:= np.linspace(-5*np.pi, 5*np.pi, 50)), \"y\": 5*np.sin(x)})\n",
    "\n",
    "(\n",
    "    df1.hvplot.line(x=\"x1\", y=\"y\", frame_width=200, aspect=1) +\n",
    "    df2.hvplot.line(x=\"x2\", y=\"y\", frame_width=200, aspect=1, shared_axes=False)\n",
    ").opts(title=\"y axes shared\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04b7b410-03ce-45e6-85fd-81778b66f6b7",
   "metadata": {},
   "source": [
    "Axes are also shared by default for layouts created with the [`subplots`](option-subplots) option."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4d923ea4-64fe-48f5-8057-de0587823258",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "df.hvplot.scatter(\n",
    "    x=\"bill_length_mm\", y=\"bill_depth_mm\", by=\"sex\",\n",
    "    subplots=True, frame_width=200, aspect=1,\n",
    ").opts(title=\"x and y axes shared\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9071aadd-db59-4030-9b19-046615a35b31",
   "metadata": {},
   "source": [
    "This can be disabled with `shared_axes=False`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f0c29d3e-ac9a-4219-8dd4-5474d4d10ddc",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "df.hvplot.scatter(\n",
    "    x=\"bill_length_mm\", y=\"bill_depth_mm\", by=\"sex\",\n",
    "    subplots=True, frame_width=200, aspect=1, shared_axes=False,\n",
    ").opts(title=\"x and y axes not shared\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68986eab-fcf6-49ed-bba5-2c9895af0bad",
   "metadata": {},
   "source": [
    "(option-subcoordinate_y)=\n",
    "## `subcoordinate_y`\n",
    "\n",
    "hvPlot enables you to create overlays where each element has its own distinct y-axis subcoordinate system, which is particularly useful to analyse multiple timeseries. To activate this feature that automatically distributes overlay elements along the y-axis, set the `subcoordinate_y` option to `True`. `subcoordinate_y` also accepts a dictionary of related options, for example set `subcoordinate_y={\"subcoordinate_scale\": 2}` to increase the scale of each sub-plot, resulting in each curve’s vertical range overlapping 50% with its adjacent elements. Additionally, the y-axis wheel zoom will apply to each curve’s respective sub-coordinate y-axis, rather than the global coordinate frame. More information about this feature can be found in [HoloViews’ documentation](https://holoviews.org/user_guide/Customizing_Plots.html#subcoordinate-y-axis).\n",
    "\n",
    "Use the wheel zoom on the plots below to zoom in all the time series simultaneously."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c9669357-f702-4e49-80f7-e69797d8469e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.stocks(\"pandas\")\n",
    "df.hvplot.line(subcoordinate_y=True, title=\"subcoordinate_y=True\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e1b2d8c0-d9dd-4db5-81ed-e940aaed79e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.stocks(\"pandas\")\n",
    "\n",
    "df.hvplot.line(subcoordinate_y={\"subcoordinate_scale\": 2}, title=\"50% overlapping subcoordinate_y\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "147fa90b-d002-4ef3-aa35-35c16cdfa2e6",
   "metadata": {},
   "source": [
    "(option-title)=\n",
    "## `title`\n",
    "\n",
    "The `title` option allows to set the overall plot title.\n",
    "\n",
    ":::{note}\n",
    "For simple plots, setting the plot title with `title` or with the [`label`](option-label) option both lead to a similar visual output. However, the HoloViews object returned will only have its `label` attribute set when the `label` option is used.\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d7281136-a33d-4553-9b50-a2ac430e0f04",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "df.hvplot.scatter(\"bill_depth_mm\", \"bill_length_mm\", width=400, title=\"Plot title\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3cd867cf-7019-47b2-a5e1-c65f9a16f3ba",
   "metadata": {},
   "source": [
    "(option-xaxis)=\n",
    "## `xaxis`\n",
    "\n",
    "Control the x-axis location and display with `xaxis`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "549a5acb-a960-4867-8c56-983ec48bc93b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "plot_opts = dict(x=\"bill_depth_mm\", y=\"bill_length_mm\", frame_width=200, aspect=1)\n",
    "\n",
    "(\n",
    "    df.hvplot.scatter(xaxis=\"bottom\", title=\"xaxis=bottom (default)\", **plot_opts) +\n",
    "    df.hvplot.scatter(xaxis=\"bottom-bare\", title=\"xaxis=bottom-bare\", **plot_opts) +\n",
    "    df.hvplot.scatter(xaxis=\"top\", title=\"xaxis=top\", **plot_opts) +\n",
    "    df.hvplot.scatter(xaxis=\"top-bare\", title=\"xaxis=top-bare\", **plot_opts) +\n",
    "    df.hvplot.scatter(xaxis=\"bare\", title=\"xaxis=bare\", **plot_opts) +\n",
    "    df.hvplot.scatter(xaxis=None, title=\"xaxis=None\", **plot_opts) +\n",
    "    df.hvplot.scatter(xaxis=True, title=\"xaxis=True\", **plot_opts) +\n",
    "    df.hvplot.scatter(xaxis=False, title=\"xaxis=False\", **plot_opts)\n",
    ").cols(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "31451937-ea24-4400-b882-66aa94a72ea1",
   "metadata": {},
   "source": [
    "(option-yaxis)=\n",
    "## `yaxis`\n",
    "\n",
    "Control the y-axis location and display with `yaxis`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "85ff0a6f-ffc7-42d5-9d72-fc9d82006128",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "plot_opts = dict(x=\"bill_depth_mm\", y=\"bill_length_mm\", frame_width=200, aspect=1)\n",
    "\n",
    "(\n",
    "    df.hvplot.scatter(yaxis=\"left\", title=\"yaxis=left (default)\", **plot_opts) +\n",
    "    df.hvplot.scatter(yaxis=\"left-bare\", title=\"yaxis=left-bare\", **plot_opts) +\n",
    "    df.hvplot.scatter(yaxis=\"right\", title=\"yaxis=right\", **plot_opts) +\n",
    "    df.hvplot.scatter(yaxis=\"right-bare\", title=\"yaxis=right-bare\", **plot_opts) +\n",
    "    df.hvplot.scatter(yaxis=\"bare\", title=\"yaxis=bare\", **plot_opts) +\n",
    "    df.hvplot.scatter(yaxis=None, title=\"yaxis=None\", **plot_opts) +\n",
    "    df.hvplot.scatter(yaxis=True, title=\"yaxis=True\", **plot_opts) +\n",
    "    df.hvplot.scatter(yaxis=False, title=\"yaxis=False\", **plot_opts)\n",
    ").cols(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6972a77c-629c-4040-9019-51eb5a55ea36",
   "metadata": {},
   "source": [
    "(option-xformatter)=\n",
    "(option-yformatter)=\n",
    "(option-xformatter_yformatter)=\n",
    "## `xformatter / yformatter`\n",
    "\n",
    "These options allow to format the x and y tick labels. They accept a `str` object, or a Bokeh or Matplotlib formatter instance (depending on the active plotting backend).\n",
    "\n",
    "When set to a `str` object, these formatters are:\n",
    "- Bokeh: [`PrintfTickFormatter`](https://docs.bokeh.org/en/latest/docs/reference/models/formatters.html#bokeh.models.PrintfTickFormatter) (*printf/old-style* format string as used with the `%` operator); note that Bokeh computes the labels in the front-end using the JavaScript library [sprintf.js](https://github.com/alexei/sprintf.js), so the implementation can slightly differ from Python's *printf/old-style* format string.\n",
    "- Matplotlib: [`StrMethodFormatter`](https://matplotlib.org/stable/api/ticker_api.html#matplotlib.ticker.StrMethodFormatter) (*new-style* format string as used by `str.format`) if the string contains a reference to the format variable (available keys are `x` and `pos`, e.g. `'{x} {pos}'`), [`FormatStrFormatter`](https://matplotlib.org/stable/api/ticker_api.html#matplotlib.ticker.FormatStrFormatter) (*[printf/old-style](https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting)* format string as used with the `%` operator) otherwise.\n",
    "\n",
    "Bokeh's `PrintfTickFormatter` can be useful for simple number formatting and other simple cases, you can find its specification below. Matplotlib's `StrMethodFormatter` offers all the power of Python's `str.format`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a46f4698-0c07-4b57-b92c-f2ee31e1c7ce",
   "metadata": {},
   "source": [
    ":::{dropdown} Bokeh `PrintfTickFormatter` specification\n",
    "The number format, as defined as follows:\n",
    "\n",
    "The placeholders in the format string are marked by `%` and are followed by one or more of these elements, in this order:\n",
    "\n",
    "* An optional number followed by a `$` sign that selects which argument index to use for the value. If not specified, arguments will be placed in the same order as the placeholders in the input string.\n",
    "* An optional `+` sign that forces to precede the result with a plus or minus sign on numeric values. By default, only the `-` sign is used on negative numbers.\n",
    "* An optional padding specifier that says what character to use for padding (if specified). Possible values are `0` or any other character preceded by a `'` (single quote). The default is to pad with *spaces*.\n",
    "* An optional `-` sign, that causes `sprintf` to left-align the result of this placeholder. The default is to right-align the result.\n",
    "* An optional number, that says how many characters the result should have. If the value to be returned is shorter than this number, the result will be padded. When used with the `j` (JSON) type specifier, the padding length specifies the tab size used for indentation.\n",
    "* An optional precision modifier, consisting of a `.` (dot) followed by a number, that says how many digits should be displayed for floating point numbers. When used with the `g` type specifier, it specifies the number of significant digits. When used on a string, it causes the result to be truncated.\n",
    "* A type specifier that can be any of:\n",
    "    * `%` — yields a literal `%` character\n",
    "    * `b` — yields an integer as a binary number\n",
    "    * `c` — yields an integer as the character with that ASCII value\n",
    "    * `d` or `i` — yields an integer as a signed decimal number\n",
    "    * `e` — yields a float using scientific notation\n",
    "    * `u` — yields an integer as an unsigned decimal number\n",
    "    * `f` — yields a float as is; see notes on precision above\n",
    "    * `g` — yields a float as is; see notes on precision above\n",
    "    * `o` — yields an integer as an octal number\n",
    "    * `s` — yields a string as is\n",
    "    * `t` — yields `true` or `false`\n",
    "    * `T` — yields the type of the argument<sup><a href=\"#fn-1\" name=\"fn-ref-1\">1</a></sup>\n",
    "    * `v` — yields the primitive value of the specified argument\n",
    "    * `x` — yields an integer as a hexadecimal number (lower-case)\n",
    "    * `X` — yields an integer as a hexadecimal number (upper-case)\n",
    "    * `j` — yields a JavaScript object or array as a JSON encoded string\n",
    ":::\n",
    "\n",
    "For Bokeh plots, [`NumeralTickFormatter`](https://docs.bokeh.org/en/latest/docs/reference/models/formatters.html#bokeh.models.NumeralTickFormatter) is a much more appropriate formatter for a wider range of number format options. You can find its complete specification below (Bokeh's implementation leverages the JavaScript library `numbro`, visit [their format reference](https://numbrojs.com/old-format.html) for more information):\n",
    "\n",
    ":::{dropdown} Bokeh `NumericalTickFormatter` specification\n",
    "**NUMBERS**\n",
    "\n",
    "| Number     | Format         | String        |\n",
    "| ---------- | -------------- | ------------- |\n",
    "| 10000      | `'0,0.0000'`   | 10,000.0000   |\n",
    "| 10000.23   | `'0,0'`        | 10,000        |\n",
    "| 10000.23   | `'+0,0'`       | +10,000       |\n",
    "| -10000     | `'0,0.0'`      | -10,000.0     |\n",
    "| 10000.1234 | `'0.000'`      | 10000.123     |\n",
    "| 10000.1234 | `'0[.]00000'`  | 10000.12340   |\n",
    "| -10000     | `'(0,0.0000)'` | (10,000.0000) |\n",
    "| -0.23      | `'.00'`        | -.23          |\n",
    "| -0.23      | `'(.00)'`      | (.23)         |\n",
    "| 0.23       | `'0.00000'`    | 0.23000       |\n",
    "| 0.23       | `'0.0[0000]'`  | 0.23          |\n",
    "| 1230974    | `'0.0a'`       | 1.2m          |\n",
    "| 1460       | `'0 a'`        | 1 k           |\n",
    "| -104000    | `'0a'`         | -104k         |\n",
    "| 1          | `'0o'`         | 1st           |\n",
    "| 52         | `'0o'`         | 52nd          |\n",
    "| 23         | `'0o'`         | 23rd          |\n",
    "| 100        | `'0o'`         | 100th         |\n",
    "\n",
    "**CURRENCY**\n",
    "\n",
    "| Number    | Format         | String      |\n",
    "| --------- | -------------- | ----------- |\n",
    "| 1000.234  | `'$0,0.00'`    | \\$1,000.23  |\n",
    "| 1000.2    | `'0,0[.]00 $'` | 1,000.20 \\$ |\n",
    "| 1001      | `'$ 0,0[.]00'` | \\$ 1,001    |\n",
    "| -1000.234 | `'($0,0)'`     | (\\$1,000)   |\n",
    "| -1000.234 | `'$0.00'`      | -\\$1000.23  |\n",
    "| 1230974   | `'($ 0.00 a)'` | \\$ 1.23 m   |\n",
    "\n",
    "**BYTES**\n",
    "\n",
    "| Number        | Format      | String   |\n",
    "| ------------- | ----------- | -------- |\n",
    "| 100           | `'0b'`      | 100B     |\n",
    "| 2048          | `'0 b'`     | 2 KB     |\n",
    "| 7884486213    | `'0.0b'`    | 7.3GB    |\n",
    "| 3467479682787 | `'0.000 b'` | 3.154 TB |\n",
    "\n",
    "**PERCENTAGES**\n",
    "\n",
    "| Number      | Format        | String   |\n",
    "| ----------- | ------------- | -------- |\n",
    "| 1           | `'0%'`        | 100%     |\n",
    "| 0.974878234 | `'0.000%'`    | 97.488%  |\n",
    "| -0.43       | `'0 %'`       | -43 %    |\n",
    "| 0.43        | `'(0.000 %)'` | 43.000 % |\n",
    "\n",
    "**TIME**\n",
    "\n",
    "| Number | Format       | String   |\n",
    "| ------ | ------------ | -------- |\n",
    "| 25     | `'00:00:00'` | 0:00:25  |\n",
    "| 238    | `'00:00:00'` | 0:03:58  |\n",
    "| 63846  | `'00:00:00'` | 17:44:06 |\n",
    ":::\n",
    "\n",
    "This table contains a subset of common number formats that can be set with `NumeralTickFormatter`:\n",
    "\n",
    "| Format      | Example Input | Output      | Use Case                         |\n",
    "| ----------- | ------------- | ----------- | -------------------------------- |\n",
    "| `'0,0'`     | 12345.67      | 12,346      | General whole numbers            |\n",
    "| `'0.0a'`    | 1230000       | 1.2m        | Large numbers (compact form)     |\n",
    "| `'0%'`      | 0.45          | 45%         | Percent values                   |\n",
    "| `'0.0'`     | 123.456       | 123.5       | One decimal place                |\n",
    "| `'0.00'`    | 123.456       | 123.46      | Two decimal places               |\n",
    "| `'$0,0'`    | 12345         | \\$12,345    | Financial (whole dollar)         |\n",
    "| `'$0,0.00'` | 12345.67      | \\$12,345.67 | Financial (cents included)       |\n",
    "| `'0.00e+0'` | 0.0000123     | 1.23e-5     | Scientific notation (2 decimals) |\n",
    "| `'0e+0'`    | 123000000     | 1e+8        | Scientific notation (rounded)    |\n",
    "\n",
    "For datetime formatting:\n",
    "- Bokeh offers [DatetimeTickFormatter](https://docs.bokeh.org/en/latest/docs/reference/models/formatters.html#bokeh.models.DatetimeTickFormatter).\n",
    "- Matplotlib offers a few [date formatters](https://matplotlib.org/stable/api/dates_api.html#date-formatters), including the simple [DateFormatter](https://matplotlib.org/stable/api/dates_api.html#matplotlib.dates.DateFormatter) that uses `strftime` format strings.\n",
    "\n",
    "Visit [this page](https://docs.bokeh.org/en/latest/docs/user_guide/styling/plots.html#tick-label-formats) from Bokeh's user guide to more explanation about Bokeh's formatters."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "29f9c48d-6cc3-45c2-a4fb-7a92c110b536",
   "metadata": {},
   "source": [
    "### Bokeh\n",
    "\n",
    "This example sets a simple *printf* style y-formatter and a custom `DatetimeTickFormatter` x-formatter that sets the date format when in the days range and a context (find more information on datetime tick context in [Bokeh's documentation](https://docs.bokeh.org/en/latest/docs/user_guide/styling/plots.html#datetime-tick-context))."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c962168-a50a-4f22-9a63-8e5dc083e8c3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "from bokeh.models import DatetimeTickFormatter, RELATIVE_DATETIME_CONTEXT\n",
    "\n",
    "df = hvplot.sampledata.apple_stocks(\"pandas\").set_index(\"date\").loc[\"2023-01\"]\n",
    "df.hvplot.line(\n",
    "    y=\"open\", width=500,\n",
    "    xformatter=DatetimeTickFormatter(days=\"%B %d\", context=RELATIVE_DATETIME_CONTEXT()),\n",
    "    yformatter=\"$%.2f\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ed2a596b-4daa-48d5-9d81-c2dae4efc0db",
   "metadata": {},
   "source": [
    "This example sets a `NumeralTickFormatter` y-formatter to format the volume in a more consice way."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a0ad2b6c-2305-4be0-93f5-fe168256bc43",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "from bokeh.models import NumeralTickFormatter\n",
    "\n",
    "df = hvplot.sampledata.apple_stocks(\"pandas\").set_index(\"date\").loc[\"2023-01\"]\n",
    "df.hvplot.line(y=\"volume\", width=500, yformatter=NumeralTickFormatter(format=\"0.0a\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0b8a269-0202-42ae-82a7-1be3e733f3b8",
   "metadata": {},
   "source": [
    "### Matplotlib"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d23c8415-f0ad-4ab2-8755-0e5019d9c55f",
   "metadata": {},
   "source": [
    "These two examples set a `DateFormatter` x-formatter, and an *printf* and a *str.format* y-formatters, respectively."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0aea8608-3ec9-4eaa-8087-2bbe078e0104",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import matplotlib as mpl\n",
    "hvplot.extension(\"matplotlib\")\n",
    "\n",
    "df = hvplot.sampledata.apple_stocks(\"pandas\").set_index(\"date\").loc[\"2023-01\"]\n",
    "\n",
    "df.hvplot.line(y=\"open\", xformatter=mpl.dates.DateFormatter(\"%Y-%m-%d\"), yformatter=\"$%.2f\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "57519fbb-d706-4200-8cb6-d791754c2ead",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "hvplot.extension(\"matplotlib\")\n",
    "\n",
    "df = hvplot.sampledata.apple_stocks(\"pandas\").set_index(\"date\").loc[\"2023-01\"]\n",
    "\n",
    "df.hvplot.line(y=\"open\", xformatter=mpl.dates.DateFormatter(\"%Y-%m-%d\"), yformatter=\"${x:.2f} | pos={pos}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87d12cb2-8f3e-478e-9c1f-9afa73c2cb0a",
   "metadata": {},
   "source": [
    "(option-xlabel)=\n",
    "(option-ylabel)=\n",
    "(option-clabel)=\n",
    "(option-xlabel_ylabel_clabel)=\n",
    "## `xlabel / ylabel / clabel`\n",
    "\n",
    "These options are useful for overwriting the default label values, which are by default automatically set from the variable names."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1eb60e56-89fa-4078-bd6a-99bd2e774343",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "df.hvplot.scatter(\n",
    "    x=\"bill_depth_mm\", y=\"bill_length_mm\", color=\"body_mass_g\", width=400,\n",
    "    xlabel=\"Bill depth [mm]\", ylabel=\"Bill length [mm]\", clabel=\"Body mass [g]\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b187280b-d2b1-463f-81f1-486e397b334c",
   "metadata": {},
   "source": [
    "(option-xlim)=\n",
    "(option-ylim)=\n",
    "(option-xlim_ylim)=\n",
    "## `xlim / ylim`\n",
    "\n",
    "The x- and y-axis ranges can be defined with the `xlim` and `ylim` options, respectively. These options accept a 2-tuple representing the minimum and maximum bounds of the plotted ranged. One bound can be left unset by using `None` (e.g. `xlim=(10, None)` means there is no upper bound).\n",
    "\n",
    "If [`tiles`](option-tiles) is provided and the `xlim` and `ylim` are in `lat`/`lon` coordinates, they will be automatically transformed to Web Mercator coordinates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e3ba7cc3-b2a3-4a15-9451-7972a68c4478",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "plot_opts = dict(x=\"bill_depth_mm\", y=\"bill_length_mm\", height=200, width=200, shared_axes=False)\n",
    "(\n",
    "    df.hvplot.scatter(xlim=(18, None), title=\"xlim=(18, None)\", **plot_opts) +\n",
    "    df.hvplot.scatter(xlim=(None, 18), title=\"xlim=(None, 18)\", **plot_opts) +\n",
    "    df.hvplot.scatter(xlim=(16, 20), title=\"xlim=(16, 20)\", **plot_opts) +\n",
    "    df.hvplot.scatter(ylim=(45, None), title=\"ylim=(45, None)\", **plot_opts) +\n",
    "    df.hvplot.scatter(ylim=(None, 45), title=\"ylim=(None, 45)\", **plot_opts) +\n",
    "    df.hvplot.scatter(ylim=(40, 50), title=\"ylim=(40, 50)\", **plot_opts)\n",
    ").cols(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf9a1b07-21a0-4ea1-9eb9-5b796b72294c",
   "metadata": {},
   "source": [
    "For datetime axes, the bounds are expected to be in a datetime value like a `pandas.Timestamp` object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d3ee8b56-21cb-4089-b643-986a175f2970",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = hvplot.sampledata.stocks(\"pandas\").set_index(\"date\")\n",
    "\n",
    "df.hvplot.line(width=500, xlim=(pd.Timestamp(\"2021\"), pd.Timestamp(\"2023\")))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b052eb3f-2e8e-47e8-a2c2-e152a4d1f378",
   "metadata": {},
   "source": [
    "(option-xticks)=\n",
    "(option-yticks)=\n",
    "(option-cticks)=\n",
    "(option-xticks_yticks_cticks)=\n",
    "## `xticks / yticks / cticks`\n",
    "\n",
    "`xticks` `yticks` allow to control the number and/or location of the x- and y-axis ticks. `cticks` has the same effect on the colorbar axis."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "89242e58-5c54-4b56-a111-7d92b0b3fa4e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import numpy as np\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "plot_opts = dict(x=\"bill_depth_mm\", y=\"bill_length_mm\", frame_width=200, aspect=1, fontsize={\"title\": \"10pt\"})\n",
    "(\n",
    "    df.hvplot.scatter(xticks=None, title=\"xticks=None (default)\", **plot_opts) +\n",
    "    df.hvplot.scatter(xticks=2, title=\"xticks=2\", **plot_opts) +\n",
    "    df.hvplot.scatter(xticks=[15, 17.5, 20], title=\"xticks=[15, 17.5, 20]\", **plot_opts) +\n",
    "    df.hvplot.scatter(xticks=np.arange(10, 25, 1), title=\"xticks=np.arange(10, 25, 1)\", **plot_opts) +\n",
    "    df.hvplot.scatter(xticks=[(15, \"small\"), (20, \"big\")], title='xticks=[(15, \"small\"), (20, \"big\")]', **plot_opts) +\n",
    "    df.hvplot.scatter(xaxis=None, yaxis=None, c=\"white\", **plot_opts) +\n",
    "    df.hvplot.scatter(yticks=None, title=\"yticks=None (default)\", **plot_opts) +\n",
    "    df.hvplot.scatter(yticks=2, title=\"yticks=2\", **plot_opts) +\n",
    "    df.hvplot.scatter(yticks=[35, 45, 55], title=\"yticks=[35, 45, 55]\", **plot_opts) +\n",
    "    df.hvplot.scatter(yticks=np.arange(30, 65, 5), title=\"yticks=np.arange(30, 65, 5)\", **plot_opts) +\n",
    "    df.hvplot.scatter(yticks=[(35, \"small\"), (55, \"big\")], title='yticks=[(35, \"small\"), (55, \"big\")]', **plot_opts) +\n",
    "    df.hvplot.scatter(xaxis=None, yaxis=None, c=\"white\", **plot_opts)\n",
    ").cols(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a6395a6e-817c-4619-869a-0a623802df8d",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = hvplot.sampledata.stocks(\"pandas\").set_index(\"date\")\n",
    "\n",
    "df.hvplot.line(width=500, xticks=pd.date_range(\"2019\", \"2024\", freq=\"6ME\").to_list(), rot=45)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bfc221af-6d98-4d87-8ff7-e564096f7a11",
   "metadata": {},
   "source": [
    "When creating a Bokeh plot, `xaxis` and `yaxis` also accept a custom [Bokeh ticker](https://docs.bokeh.org/en/latest/docs/reference/models/tickers.html) object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2dd5391e-e4dc-4538-8ddf-a157961a521b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import bokeh as bk\n",
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.stocks(\"pandas\").set_index(\"date\").loc[\"2023-01\"]\n",
    "df.hvplot.line(\n",
    "    width=500,\n",
    "    xticks=bk.models.DaysTicker(days=list(range(1, 32, 7))),\n",
    "    yticks=bk.models.SingleIntervalTicker(interval=1),\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00a4176e-404a-4020-979f-ae1c3e931634",
   "metadata": {},
   "source": [
    "`cticks` accept a similar set of values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2956e0cf-97c7-4fc2-9744-7c282a288b15",
   "metadata": {},
   "outputs": [],
   "source": [
    "import bokeh\n",
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "plot_opts = dict(\n",
    "    x=\"bill_depth_mm\", y=\"bill_length_mm\", color=\"body_mass_g\",\n",
    "    frame_width=200, aspect=1, fontsize={\"title\": \"10pt\"}\n",
    ")\n",
    "(\n",
    "    df.hvplot.scatter(cticks=None, title=\"cticks=None (default)\", **plot_opts) +\n",
    "    df.hvplot.scatter(cticks=2, title=\"cticks=2\", **plot_opts) +\n",
    "    df.hvplot.scatter(cticks=[3000, 4500, 6000], title=\"cticks=[3000, 4500, 6000]\", **plot_opts) +\n",
    "    df.hvplot.scatter(cticks=np.arange(3000, 6500, 500), title=\"cticks=np.arange(3000, 6500, 500)\", **plot_opts) +\n",
    "    df.hvplot.scatter(cticks=[(3000, \"small\"), (6000, \"big\")], title='cticks=[(3000, \"small\"), (6000, \"big\")]', **plot_opts) +\n",
    "    df.hvplot.scatter(cticks=bokeh.models.SingleIntervalTicker(interval=1000), title='cticks=bokeh.models.Ticker()', **plot_opts)\n",
    ").cols(2)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
